package com.nku.mason.masonframework.core.tools;

import java.lang.annotation.Annotation;
import java.util.HashSet;
import java.util.Set;

import com.nku.mason.masonframework.core.annotations.Controller;
import com.nku.mason.masonframework.core.annotations.Service;
import com.nku.mason.masonframework.util.ClassUtil;
/**
 * 类操作工具类
 * @author Mason
 * @date 2017年3月13日
 */
public final class ClassTool {
	
	private ClassTool(){
		//私有构造器，防止外部实例化
	}
	
	//用户存放所加载的类
	private static Set<Class<?>> CLASS_SET;
	
	static {
		String basePackage = ConfigTool.getAppBasePackage();
		CLASS_SET = ClassUtil.getClassSet(basePackage);
	}
	
	/**
	 * 获取应用包名下的所有类
	 * @return
	 */
	public static Set<Class<?>> getClassSet(){
		return CLASS_SET;
	}
	
	/**
	 * 获取应用包名下的所有Service类
	 * @return
	 */
	public static Set<Class<?>> getServiceClassSet(){
		Set<Class<?>> classSet = new HashSet<Class<?>>();
		for(Class<?> cls : CLASS_SET){
			if (cls.isAnnotationPresent(Service.class)) {
				classSet.add(cls);
			}
		}
		
		return classSet;
	}
	
	/**
	 * 获取应用包名下所有Controller类 
	 * @return
	 */
	public static Set<Class<?>> getControllerClassSet(){
		Set<Class<?>> classSet = new HashSet<Class<?>>();
		for(Class<?> cls : CLASS_SET){
			if (cls.isAnnotationPresent(Controller.class)) {
				classSet.add(cls);
			}
		}
		
		return classSet;
	}
	
	/**
	 * 获取应用包名下所有Bean类(包括:Service，Controller等)
	 * @return
	 */
	public static Set<Class<?>> getBeanClassSet(){
		Set<Class<?>> beanClassSet = new HashSet<Class<?>>();
		beanClassSet.addAll(getServiceClassSet());
		beanClassSet.addAll(getControllerClassSet());
		return beanClassSet;
	}
	
	/**
	 * 获取应用包名下某父类(或接口)的所有子类(或实现类)
	 * @param superClass
	 * @return
	 */
	public static Set<Class<?>> getClassSetBySuper(Class<?> superClass){
		Set<Class<?>> classSet = new HashSet<Class<?>>();
		for(Class<?> cls : CLASS_SET){
			if (cls.isAssignableFrom(superClass) && !superClass.equals(cls)) {
				classSet.add(cls);
			}
		}
		return classSet;
	}
	
	/**
	 * 获取应用包名下带有某注解的所有类
	 * @param annotationClass
	 * @return
	 */
	public static Set<Class<?>> getClassSetByAnnotation(Class<? extends Annotation> annotationClass){
		Set<Class<?>> classSet = new HashSet<Class<?>>();
		for(Class<?> cls : CLASS_SET){
			if (cls.isAnnotationPresent(annotationClass)) {
				classSet.add(cls);
			}
		}
		
		return classSet;
	}
}




























